home *** CD-ROM | disk | FTP | other *** search
/ LG Super CD / LG Super CD.iso / bitpim / bitpim-0.62-setup.exe / {app} / bitpim.exe / pstats.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2003-11-06  |  22.4 KB  |  671 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.3)
  3.  
  4. import os
  5. import time
  6. import marshal
  7. import re
  8. __all__ = [
  9.     'Stats']
  10.  
  11. class Stats:
  12.     
  13.     def __init__(self, *args):
  14.         if not len(args):
  15.             arg = None
  16.         else:
  17.             arg = args[0]
  18.             args = args[1:]
  19.         self.init(arg)
  20.         self.add(*args)
  21.  
  22.     
  23.     def init(self, arg):
  24.         self.all_callees = None
  25.         self.files = []
  26.         self.fcn_list = None
  27.         self.total_tt = 0
  28.         self.total_calls = 0
  29.         self.prim_calls = 0
  30.         self.max_name_len = 0
  31.         self.top_level = { }
  32.         self.stats = { }
  33.         self.sort_arg_dict = { }
  34.         self.load_stats(arg)
  35.         trouble = 1
  36.         
  37.         try:
  38.             self.get_top_level_stats()
  39.             trouble = 0
  40.         finally:
  41.             pass
  42.  
  43.  
  44.     
  45.     def load_stats(self, arg):
  46.         if not arg:
  47.             self.stats = { }
  48.         elif type(arg) == type(''):
  49.             f = open(arg, 'rb')
  50.             self.stats = marshal.load(f)
  51.             f.close()
  52.             
  53.             try:
  54.                 file_stats = os.stat(arg)
  55.                 arg = time.ctime(file_stats.st_mtime) + '    ' + arg
  56.             except:
  57.                 pass
  58.  
  59.             self.files = [
  60.                 arg]
  61.         elif hasattr(arg, 'create_stats'):
  62.             arg.create_stats()
  63.             self.stats = arg.stats
  64.             arg.stats = { }
  65.         
  66.         if not (self.stats):
  67.             raise TypeError, 'Cannot create or construct a ' + `self.__class__` + " object from '" + `arg` + "'"
  68.         
  69.         return None
  70.  
  71.     
  72.     def get_top_level_stats(self):
  73.         for cc, nc, tt, ct, callers in self.stats.items():
  74.             self.total_calls += nc
  75.             self.prim_calls += cc
  76.             self.total_tt += tt
  77.             if len(func_std_string(func)) > self.max_name_len:
  78.                 self.max_name_len = len(func_std_string(func))
  79.                 continue
  80.             self if callers.has_key(('jprofile', 0, 'profiler')) else self
  81.         
  82.  
  83.     
  84.     def add(self, *arg_list):
  85.         if not arg_list:
  86.             return self
  87.         
  88.         if len(arg_list) > 1:
  89.             self.add(*arg_list[1:])
  90.         
  91.         other = arg_list[0]
  92.         if type(self) != type(other) or self.__class__ != other.__class__:
  93.             other = Stats(other)
  94.         
  95.         self.files += other.files
  96.         self.total_calls += other.total_calls
  97.         self.prim_calls += other.prim_calls
  98.         self.total_tt += other.total_tt
  99.         for func in other.top_level:
  100.             self.top_level[func] = None
  101.         
  102.         self.fcn_list = None
  103.         for func, stat in other.stats.iteritems():
  104.             self.stats[func] = add_func_stats(old_func_stat, stat)
  105.         
  106.         return self
  107.  
  108.     
  109.     def dump_stats(self, filename):
  110.         f = file(filename, 'wb')
  111.         
  112.         try:
  113.             marshal.dump(self.stats, f)
  114.         finally:
  115.             f.close()
  116.  
  117.  
  118.     sort_arg_dict_default = {
  119.         'calls': (((1, -1),), 'call count'),
  120.         'cumulative': (((3, -1),), 'cumulative time'),
  121.         'file': (((4, 1),), 'file name'),
  122.         'line': (((5, 1),), 'line number'),
  123.         'module': (((4, 1),), 'file name'),
  124.         'name': (((6, 1),), 'function name'),
  125.         'nfl': (((6, 1), (4, 1), (5, 1)), 'name/file/line'),
  126.         'pcalls': (((0, -1),), 'call count'),
  127.         'stdname': (((7, 1),), 'standard name'),
  128.         'time': (((2, -1),), 'internal time') }
  129.     
  130.     def get_sort_arg_defs(self):
  131.         if not (self.sort_arg_dict):
  132.             self.sort_arg_dict = dict = { }
  133.             bad_list = { }
  134.             for word, tup in self.sort_arg_dict_default.iteritems():
  135.                 fragment = word
  136.                 while fragment:
  137.                     if not fragment:
  138.                         break
  139.                     
  140.                     if fragment in dict:
  141.                         bad_list[fragment] = 0
  142.                         break
  143.                     
  144.                     dict[fragment] = tup
  145.                     fragment = fragment[:-1]
  146.             
  147.             for word in bad_list:
  148.                 del dict[word]
  149.             
  150.         
  151.         return self.sort_arg_dict
  152.  
  153.     
  154.     def sort_stats(self, *field):
  155.         if not field:
  156.             self.fcn_list = 0
  157.             return self
  158.         
  159.         if len(field) == 1 and type(field[0]) == type(1):
  160.             field = [
  161.                 {
  162.                     -1: 'stdname',
  163.                     0: 'calls',
  164.                     1: 'time',
  165.                     2: 'cumulative' }[field[0]]]
  166.         
  167.         sort_arg_defs = self.get_sort_arg_defs()
  168.         sort_tuple = ()
  169.         self.sort_type = ''
  170.         connector = ''
  171.         for word in field:
  172.             sort_tuple = sort_tuple + sort_arg_defs[word][0]
  173.             self.sort_type += connector + sort_arg_defs[word][1]
  174.             connector = ', '
  175.         
  176.         stats_list = []
  177.         for cc, nc, tt, ct, callers in self.stats.iteritems():
  178.             stats_list.append((cc, nc, tt, ct) + func + (func_std_string(func), func))
  179.         
  180.         stats_list.sort(TupleComp(sort_tuple).compare)
  181.         self.fcn_list = fcn_list = []
  182.         for tuple in stats_list:
  183.             fcn_list.append(tuple[-1])
  184.         
  185.         return self
  186.  
  187.     
  188.     def reverse_order(self):
  189.         if self.fcn_list:
  190.             self.fcn_list.reverse()
  191.         
  192.         return self
  193.  
  194.     
  195.     def strip_dirs(self):
  196.         oldstats = self.stats
  197.         self.stats = newstats = { }
  198.         max_name_len = 0
  199.         for cc, nc, tt, ct, callers in oldstats.iteritems():
  200.             newfunc = func_strip_path(func)
  201.             if len(func_std_string(newfunc)) > max_name_len:
  202.                 max_name_len = len(func_std_string(newfunc))
  203.             
  204.             newcallers = { }
  205.             for func2, caller in callers.iteritems():
  206.                 newcallers[func_strip_path(func2)] = caller
  207.             
  208.             if newfunc in newstats:
  209.                 newstats[newfunc] = add_func_stats(newstats[newfunc], (cc, nc, tt, ct, newcallers))
  210.                 continue
  211.             newstats[newfunc] = (cc, nc, tt, ct, newcallers)
  212.         
  213.         old_top = self.top_level
  214.         self.top_level = new_top = { }
  215.         for func in old_top:
  216.             new_top[func_strip_path(func)] = None
  217.         
  218.         self.max_name_len = max_name_len
  219.         self.fcn_list = None
  220.         self.all_callees = None
  221.         return self
  222.  
  223.     
  224.     def calc_callees(self):
  225.         if self.all_callees:
  226.             return None
  227.         
  228.         self.all_callees = all_callees = { }
  229.         for cc, nc, tt, ct, callers in self.stats.iteritems():
  230.             if not (func in all_callees):
  231.                 all_callees[func] = { }
  232.             
  233.             for func2, caller in callers.iteritems():
  234.                 if not (func2 in all_callees):
  235.                     all_callees[func2] = { }
  236.                 
  237.                 all_callees[func2][func] = caller
  238.             
  239.         
  240.         return None
  241.  
  242.     
  243.     def eval_print_amount(self, sel, list, msg):
  244.         new_list = list
  245.         if type(sel) == type(''):
  246.             new_list = []
  247.             for func in list:
  248.                 if re.search(sel, func_std_string(func)):
  249.                     new_list.append(func)
  250.                     continue
  251.             
  252.         else:
  253.             count = len(list)
  254.             if type(sel) == type(1.0):
  255.                 if sel <= sel:
  256.                     pass
  257.                 elif sel < 1.0:
  258.                     count = int(count * sel + 0.5)
  259.                     new_list = list[:count]
  260.                 elif type(sel) == type(1):
  261.                     if sel <= sel:
  262.                         pass
  263.                     elif sel < count:
  264.                         count = sel
  265.                         new_list = list[:count]
  266.                     
  267.         if len(list) != len(new_list):
  268.             msg = msg + '   List reduced from ' + `len(list)` + ' to ' + `len(new_list)` + ' due to restriction <' + `sel` + '>\n'
  269.         
  270.         return (new_list, msg)
  271.  
  272.     
  273.     def get_print_list(self, sel_list):
  274.         width = self.max_name_len
  275.         if self.fcn_list:
  276.             list = self.fcn_list[:]
  277.             msg = '   Ordered by: ' + self.sort_type + '\n'
  278.         else:
  279.             list = self.stats.keys()
  280.             msg = '   Random listing order was used\n'
  281.         for selection in sel_list:
  282.             (list, msg) = self.eval_print_amount(selection, list, msg)
  283.         
  284.         count = len(list)
  285.         if not list:
  286.             return (0, list)
  287.         
  288.         print msg
  289.         if count < len(self.stats):
  290.             width = 0
  291.             for func in list:
  292.                 if len(func_std_string(func)) > width:
  293.                     width = len(func_std_string(func))
  294.                     continue
  295.             
  296.         
  297.         return (width + 2, list)
  298.  
  299.     
  300.     def print_stats(self, *amount):
  301.         for filename in self.files:
  302.             print filename
  303.         
  304.         if self.files:
  305.             print 
  306.         
  307.         indent = ' ' * 8
  308.         for func in self.top_level:
  309.             print indent, func_get_function_name(func)
  310.         
  311.         print indent, self.total_calls, 'function calls',
  312.         if self.total_calls != self.prim_calls:
  313.             print '(%d primitive calls)' % self.prim_calls,
  314.         
  315.         print 'in %.3f CPU seconds' % self.total_tt
  316.         print 
  317.         (width, list) = self.get_print_list(amount)
  318.         if list:
  319.             self.print_title()
  320.             for func in list:
  321.                 self.print_line(func)
  322.             
  323.             print 
  324.             print 
  325.         
  326.         return self
  327.  
  328.     
  329.     def print_callees(self, *amount):
  330.         (width, list) = self.get_print_list(amount)
  331.         if list:
  332.             self.calc_callees()
  333.             self.print_call_heading(width, 'called...')
  334.             for func in list:
  335.                 if func in self.all_callees:
  336.                     self.print_call_line(width, func, self.all_callees[func])
  337.                     continue
  338.                 self.print_call_line(width, func, { })
  339.             
  340.             print 
  341.             print 
  342.         
  343.         return self
  344.  
  345.     
  346.     def print_callers(self, *amount):
  347.         (width, list) = self.get_print_list(amount)
  348.         if list:
  349.             self.print_call_heading(width, 'was called by...')
  350.             for func in list:
  351.                 (cc, nc, tt, ct, callers) = self.stats[func]
  352.                 self.print_call_line(width, func, callers)
  353.             
  354.             print 
  355.             print 
  356.         
  357.         return self
  358.  
  359.     
  360.     def print_call_heading(self, name_size, column_title):
  361.         print 'Function '.ljust(name_size) + column_title
  362.  
  363.     
  364.     def print_call_line(self, name_size, source, call_dict):
  365.         print func_std_string(source).ljust(name_size),
  366.         if not call_dict:
  367.             print '--'
  368.             return None
  369.         
  370.         clist = call_dict.keys()
  371.         clist.sort()
  372.         name_size = name_size + 1
  373.         indent = ''
  374.         for func in clist:
  375.             name = func_std_string(func)
  376.             print indent * name_size + name + '(' + `call_dict[func]` + ')', f8(self.stats[func][3])
  377.             indent = ' '
  378.         
  379.  
  380.     
  381.     def print_title(self):
  382.         print '   ncalls  tottime  percall  cumtime  percall', 'filename:lineno(function)'
  383.  
  384.     
  385.     def print_line(self, func):
  386.         (cc, nc, tt, ct, callers) = self.stats[func]
  387.         c = str(nc)
  388.         if nc != cc:
  389.             c = c + '/' + str(cc)
  390.         
  391.         print c.rjust(9), f8(tt),
  392.         if nc == 0:
  393.             print ' ' * 8,
  394.         else:
  395.             print f8(tt / nc),
  396.         print f8(ct),
  397.         if cc == 0:
  398.             print ' ' * 8,
  399.         else:
  400.             print f8(ct / cc),
  401.         print func_std_string(func)
  402.  
  403.     
  404.     def ignore(self):
  405.         pass
  406.  
  407.  
  408.  
  409. class TupleComp:
  410.     
  411.     def __init__(self, comp_select_list):
  412.         self.comp_select_list = comp_select_list
  413.  
  414.     
  415.     def compare(self, left, right):
  416.         for index, direction in self.comp_select_list:
  417.             l = left[index]
  418.             r = right[index]
  419.             if l < r:
  420.                 return -direction
  421.             
  422.             if l > r:
  423.                 return direction
  424.                 continue
  425.         
  426.         return 0
  427.  
  428.  
  429.  
  430. def func_strip_path(func_name):
  431.     (filename, line, name) = func_name
  432.     return (os.path.basename(filename), line, name)
  433.  
  434.  
  435. def func_get_function_name(func):
  436.     return func[2]
  437.  
  438.  
  439. def func_std_string(func_name):
  440.     return '%s:%d(%s)' % func_name
  441.  
  442.  
  443. def add_func_stats(target, source):
  444.     (cc, nc, tt, ct, callers) = source
  445.     (t_cc, t_nc, t_tt, t_ct, t_callers) = target
  446.     return (cc + t_cc, nc + t_nc, tt + t_tt, ct + t_ct, add_callers(t_callers, callers))
  447.  
  448.  
  449. def add_callers(target, source):
  450.     new_callers = { }
  451.     for func, caller in target.iteritems():
  452.         new_callers[func] = caller
  453.     
  454.     for func, caller in source.iteritems():
  455.         if func in new_callers:
  456.             new_callers[func] = caller + new_callers[func]
  457.             continue
  458.         new_callers[func] = caller
  459.     
  460.     return new_callers
  461.  
  462.  
  463. def count_calls(callers):
  464.     nc = 0
  465.     for calls in callers.itervalues():
  466.         nc += calls
  467.     
  468.     return nc
  469.  
  470.  
  471. def f8(x):
  472.     return '%8.3f' % x
  473.  
  474. if __name__ == '__main__':
  475.     import cmd
  476.     
  477.     try:
  478.         import readline
  479.     except ImportError:
  480.         pass
  481.  
  482.     
  483.     class ProfileBrowser(cmd.Cmd):
  484.         
  485.         def __init__(self, profile = None):
  486.             cmd.Cmd.__init__(self)
  487.             self.prompt = '% '
  488.             if profile is not None:
  489.                 self.stats = Stats(profile)
  490.             else:
  491.                 self.stats = None
  492.  
  493.         
  494.         def generic(self, fn, line):
  495.             args = line.split()
  496.             processed = []
  497.             for term in args:
  498.                 
  499.                 try:
  500.                     processed.append(int(term))
  501.                 except ValueError:
  502.                     pass
  503.  
  504.                 
  505.                 try:
  506.                     frac = float(term)
  507.                     if frac > 1 or frac < 0:
  508.                         print 'Fraction argument mus be in [0, 1]'
  509.                         continue
  510.                     
  511.                     processed.append(frac)
  512.                 except ValueError:
  513.                     pass
  514.  
  515.                 processed.append(term)
  516.             
  517.             if self.stats:
  518.                 getattr(self.stats, fn)(*processed)
  519.             else:
  520.                 print 'No statistics object is loaded.'
  521.             return 0
  522.  
  523.         
  524.         def generic_help(self):
  525.             print 'Arguments may be:'
  526.             print '* An integer maximum number of entries to print.'
  527.             print '* A decimal fractional number between 0 and 1, controlling'
  528.             print '  what fraction of selected entries to print.'
  529.             print '* A regular expression; only entries with function names'
  530.             print '  that match it are printed.'
  531.  
  532.         
  533.         def do_add(self, line):
  534.             self.stats.add(line)
  535.             return 0
  536.  
  537.         
  538.         def help_add(self):
  539.             print 'Add profile info from given file to current statistics object.'
  540.  
  541.         
  542.         def do_callees(self, line):
  543.             return self.generic('print_callees', line)
  544.  
  545.         
  546.         def help_callees(self):
  547.             print 'Print callees statistics from the current stat object.'
  548.             self.generic_help()
  549.  
  550.         
  551.         def do_callers(self, line):
  552.             return self.generic('print_callers', line)
  553.  
  554.         
  555.         def help_callers(self):
  556.             print 'Print callers statistics from the current stat object.'
  557.             self.generic_help()
  558.  
  559.         
  560.         def do_EOF(self, line):
  561.             print ''
  562.             return 1
  563.  
  564.         
  565.         def help_EOF(self):
  566.             print 'Leave the profile brower.'
  567.  
  568.         
  569.         def do_quit(self, line):
  570.             return 1
  571.  
  572.         
  573.         def help_quit(self):
  574.             print 'Leave the profile brower.'
  575.  
  576.         
  577.         def do_read(self, line):
  578.             if line:
  579.                 
  580.                 try:
  581.                     self.stats = Stats(line)
  582.                 except IOError:
  583.                     args = None
  584.                     print args[1]
  585.                     return None
  586.  
  587.                 self.prompt = line + '% '
  588.             elif len(self.prompt) > 2:
  589.                 line = self.prompt[-2:]
  590.             else:
  591.                 print 'No statistics object is current -- cannot reload.'
  592.             return 0
  593.  
  594.         
  595.         def help_read(self):
  596.             print 'Read in profile data from a specified file.'
  597.  
  598.         
  599.         def do_reverse(self, line):
  600.             self.stats.reverse_order()
  601.             return 0
  602.  
  603.         
  604.         def help_reverse(self):
  605.             print 'Reverse the sort order of the profiling report.'
  606.  
  607.         
  608.         def do_sort(self, line):
  609.             abbrevs = self.stats.get_sort_arg_defs()
  610.             if line and not filter((lambda x, a = abbrevs: x not in a), line.split()):
  611.                 self.stats.sort_stats(*line.split())
  612.             else:
  613.                 print 'Valid sort keys (unique prefixes are accepted):'
  614.                 for key, value in Stats.sort_arg_dict_default.iteritems():
  615.                     print '%s -- %s' % (key, value[1])
  616.                 
  617.             return 0
  618.  
  619.         
  620.         def help_sort(self):
  621.             print 'Sort profile data according to specified keys.'
  622.             print "(Typing `sort' without arguments lists valid keys.)"
  623.  
  624.         
  625.         def complete_sort(self, text, *args):
  626.             return []
  627.  
  628.         
  629.         def do_stats(self, line):
  630.             return self.generic('print_stats', line)
  631.  
  632.         
  633.         def help_stats(self):
  634.             print 'Print statistics from the current stat object.'
  635.             self.generic_help()
  636.  
  637.         
  638.         def do_strip(self, line):
  639.             self.stats.strip_dirs()
  640.             return 0
  641.  
  642.         
  643.         def help_strip(self):
  644.             print 'Strip leading path information from filenames in the report.'
  645.  
  646.         
  647.         def postcmd(self, stop, line):
  648.             if stop:
  649.                 return stop
  650.             
  651.             return None
  652.  
  653.  
  654.     import sys
  655.     print 'Welcome to the profile statistics browser.'
  656.     if len(sys.argv) > 1:
  657.         initprofile = sys.argv[1]
  658.     else:
  659.         initprofile = None
  660.     
  661.     try:
  662.         ProfileBrowser(initprofile).cmdloop()
  663.         print 'Goodbye.'
  664.     except KeyboardInterrupt:
  665.         pass
  666.     except:
  667.         None<EXCEPTION MATCH>KeyboardInterrupt
  668.     
  669.  
  670. None<EXCEPTION MATCH>KeyboardInterrupt
  671.